package com.nulldev.util.net.experimental.udp2.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.Logger.Level;
import com.nulldev.util.logging.LoggerFactory;

public class SerializationUtils {
	private static SerializationUtils serializationUtils = null;
    private static final Logger LOG = LoggerFactory.getLogger(true, true);
    private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();


    private SerializationUtils() {
    }

    public static SerializationUtils getInstance() {
        if (serializationUtils == null) {
            serializationUtils = new SerializationUtils();
        }
        return serializationUtils;
    }

    public <T> byte[] serialize(T obj) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            oos.reset();
        } catch (IOException e) {
            LOG.log(Level.SEVERE, "Error IOException", e);
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    LOG.log(Level.SEVERE, "Error IOException", e);
                }
            }
        }
        byte[] byteObj = baos.toByteArray();
        baos.reset();
        return byteObj;
    }

    public <T> T deserialize(byte[] bytes) {
        T obj = null;
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;

        try {
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            obj = (T) ois.readObject();
        } catch (IOException e) {
            LOG.log(Level.SEVERE, "Error IOException", e);
        } catch (ClassNotFoundException e) {
            LOG.log(Level.SEVERE, "Error Class not found", e);
            return null;
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    LOG.log(Level.SEVERE, "Error IOException", e);
                }
            }
        }
        return obj;
    }
}
